package cn.gdchent.springbootsecurity.configbean;


import cn.gdchent.springbootsecurity.enity.UserInfoDetails;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 启动sprign boot 创建 用户角色
 */
@Configuration
public class SecurityUserDetailsServiceBean {

    @Value("${spring.security.loginType}")
    private String loginType;

    @Autowired
    private DataSource dataSource;

    /**
     *  @Override
     *             public boolean matches(CharSequence rawPassword, String encrypt) {
     *                 System.out.println("rawPassword = " + rawPassword);
     *                 System.out.println("encrypt = " + encrypt);
     *                 return Encryptors.validate(rawPassword.toString(), encrypt);
     *             }
     *
     *             @Override
     *             public String encode(CharSequence rawPassword) {
     *                 return (String) rawPassword;
     *             }
     * @return
     */
    @Bean("passwordEncoder")
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder() ;
    }

    @Bean
    public AuthenticationSuccessHandler loginSuccessHandler() {
        ObjectMapper objectMapper=new ObjectMapper();
        return new SavedRequestAwareAuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {

                Object object= authentication.getPrincipal();
                if(loginType.equalsIgnoreCase("JSON")){
                    httpServletResponse.setContentType("application/json;charset=UTF-8");
                    httpServletResponse.getWriter().write(objectMapper.writeValueAsString(object));
                    if(object instanceof UserInfoDetails){
                        UserInfoDetails userInfoDetails = (UserInfoDetails) object;
                        System.out.println("loginSuccessUserInfo:"+ userInfoDetails);
                    }
                    Object principal=SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                    if(principal instanceof UserDetails){
                        UserDetails userDetails= (UserDetails) principal;
                        if(userDetails instanceof UserInfoDetails){
                            UserInfoDetails userInfoDetails = (UserInfoDetails) object;
                            System.out.println("loginSuccessUserInfo:"+ userInfoDetails);
                            // 自定义登录成功后的返回
                            httpServletResponse.setContentType("application/json;charset=UTF-8");
                            PrintWriter out = httpServletResponse.getWriter();
                            JSONObject jsonObject=new JSONObject();
                            jsonObject.put("login","登录成功");
                            out.write(String.valueOf(jsonObject));
                            out.flush();
                        }
                    }
                }else{
                     super.onAuthenticationSuccess(httpServletRequest,httpServletResponse,authentication);
                }

            }
        };
    }

    @Bean
    public AuthenticationFailureHandler loginFailureHandler() {
        ObjectMapper objectMapper=new ObjectMapper();
        return new SimpleUrlAuthenticationFailureHandler() {
            @Override
            public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                if(loginType.equalsIgnoreCase("JSON")){
                    // 自定义登录失败的返回
                    httpServletResponse.setContentType("application/json;charset=UTF-8");
                    httpServletResponse.getWriter().write(objectMapper.writeValueAsString("登录失败"));
                    PrintWriter out = httpServletResponse.getWriter();
                    JSONObject jsonObject=new JSONObject();
                    jsonObject.put("error","用户名或密码错误");
                    out.write(String.valueOf(jsonObject));
                    out.flush();
                }else {
                     //跳转到登录
                     super.onAuthenticationFailure(httpServletRequest,httpServletResponse,e);
                }

            }
        };
    }

    @Bean
    public LogoutSuccessHandler logoutSuccessHandler(){
        return new LogoutSuccessHandler() {
            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

            }
        };
    }


}
